package com.zycfc.zsf.boot.dao.util;

import javax.sql.*;
import com.zycfc.zsf.boot.exception.type.*;
import com.zycfc.zsf.boot.exception.*;
import java.math.*;
import java.util.*;
import org.springframework.jdbc.core.*;
import java.sql.*;
import org.slf4j.*;

public class DbUtil
{
    private static final Logger log;
    
    public static Connection getConnection(final String dbType, final String address, final String dbName, final String username, final String password) throws ClassNotFoundException {
        String url = null;
        switch (dbType) {
            case "MYSQL": {
                Class.forName("com.mysql.jdbc.Driver");
                url = "jdbc:mysql://" + address + "/" + dbName + "?connectTimeout=3000&socketTimeout=3000&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useOldAliasMetadataBehavior=true";
                break;
            }
            case "ORACLE": {
                Class.forName("oracle.jdbc.OracleDriver");
                url = "jdbc:oracle:thin:@" + address + ":" + dbName;
                break;
            }
            case "ORACLE2": {
                Class.forName("oracle.jdbc.OracleDriver");
                url = "jdbc:oracle:thin:@" + address + "/" + dbName;
                break;
            }
            case "ORACLE3": {
                Class.forName("oracle.jdbc.OracleDriver");
                url = address;
                break;
            }
            case "ES": {
                Class.forName("org.elasticsearch.xpack.sql.jdbc.EsDriver");
                url = "jdbc:es://http://" + address + ":9200";
                break;
            }
            default: {
                throw new IllegalArgumentException();
            }
        }
        DbUtil.log.debug("url:{}", (Object)url);
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url, username, password);
        }
        catch (SQLException e) {
            DbUtil.log.error("", (Throwable)e);
        }
        return conn;
    }
    
    public static Connection getConnection(final DataSource dataSource) {
        try {
            return dataSource.getConnection();
        }
        catch (SQLException e) {
            DbUtil.log.error("executeUpdate", (Throwable)e);
            throw new ServiceException((IExceptionCode)ExceptionCode.DB_EXECUTE_EXCEPTION, (Throwable)e);
        }
    }
    
    public static void setObject(final PreparedStatement ps, final Object... args) {
        if (args == null) {
            return;
        }
        try {
            for (int i = 0; i < args.length; ++i) {
                final Object o = args[i];
                if (o == null) {
                    ps.setObject(i + 1, null);
                }
                else if (o instanceof String) {
                    final String val = (String)o;
                    ps.setString(i + 1, val);
                }
                else if (o instanceof Date) {
                    final Date val2 = (Date)o;
                    final java.sql.Date sqlDate = new java.sql.Date(val2.getTime());
                    ps.setDate(i + 1, sqlDate);
                }
                else if (o instanceof Timestamp) {
                    final Timestamp val3 = (Timestamp)o;
                    ps.setTimestamp(i + 1, val3);
                }
                else if (o instanceof BigDecimal) {
                    final BigDecimal val4 = (BigDecimal)o;
                    ps.setBigDecimal(i + 1, val4);
                }
                else if (o instanceof Integer) {
                    final Integer val5 = (Integer)o;
                    ps.setInt(i + 1, val5);
                }
                else if (o instanceof Long) {
                    final Long val6 = (Long)o;
                    ps.setLong(i + 1, val6);
                }
                else {
                    ps.setObject(i + 1, o);
                }
            }
        }
        catch (Exception e) {
            DbUtil.log.error("executeUpdate", (Throwable)e);
            throw new ServiceException((IExceptionCode)ExceptionCode.DB_EXECUTE_EXCEPTION, (Throwable)e);
        }
    }
    
    public static int executeUpdate(final DataSource dataSource, final String sql, final Object... args) {
        println(sql, args);
        PreparedStatement ps = null;
        final Connection conn = getConnection(dataSource);
        try {
            ps = conn.prepareStatement(sql);
            setObject(ps, args);
            final int rows = ps.executeUpdate();
            return rows;
        }
        catch (SQLException e) {
            DbUtil.log.error("executeUpdate", (Throwable)e);
            throw new ServiceException((IExceptionCode)ExceptionCode.DB_EXECUTE_EXCEPTION, (Throwable)e);
        }
        finally {
            close(conn, ps, null);
        }
    }
    
    public static int executeUpdate(final DataSource dataSource, final String sql) {
        PreparedStatement ps = null;
        final Connection conn = getConnection(dataSource);
        try {
            ps = conn.prepareStatement(sql);
            final int rows = ps.executeUpdate();
            return rows;
        }
        catch (SQLException e) {
            DbUtil.log.error("executeUpdate", (Throwable)e);
            throw new ServiceException((IExceptionCode)ExceptionCode.DB_EXECUTE_EXCEPTION, (Throwable)e);
        }
        finally {
            close(conn, ps, null);
        }
    }
    
    public static List<Map<String, Object>> executeQuery(final DataSource dataSource, final String sql, final Object... args) {
        final Connection conn = getConnection(dataSource);
        return executeQuery(conn, sql, args);
    }
    
    public static List<Map<String, Object>> executeQuery(final Connection conn, final String sql, final Object... args) {
        return executeQuery(conn, sql, true, args);
    }
    
    public static List<Map<String, Object>> executeQuery(final Connection conn, final String sql, final Boolean isCloseConn, final Object... args) {
        println(sql, args);
        PreparedStatement ps = null;
        try {
            final List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            ps = conn.prepareStatement(sql);
            final PreparedStatementSetter pss = (PreparedStatementSetter)new ArgumentPreparedStatementSetter(args);
            ps.setFetchSize(50000);
            pss.setValues(ps);
            final ResultSet rs = ps.executeQuery();
            final int count = rs.getMetaData().getColumnCount();
            int cur = 0;
            while (rs.next()) {
                ++cur;
                final Map<String, Object> maps = new LinkedHashMap<String, Object>();
                for (int i = 1; i <= count; ++i) {
                    final String name = rs.getMetaData().getColumnLabel(i);
                    maps.put(name, rs.getObject(i));
                }
                list.add(maps);
            }
            return list;
        }
        catch (SQLException e) {
            DbUtil.log.error("executeQuery", (Throwable)e);
            throw new ServiceException((IExceptionCode)ExceptionCode.DB_EXECUTE_EXCEPTION, (Throwable)e);
        }
        finally {
            if (isCloseConn) {
                close(conn, ps, null);
            }
            else if (ps != null) {
                try {
                    ps.close();
                }
                catch (SQLException e2) {
                    DbUtil.log.error("", (Throwable)e2);
                }
            }
        }
    }
    
    public static int executeUpdate(final Connection conn, final String sql, final Boolean isCloseConn, final Object... args) {
        println(sql, args);
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(sql);
            if (args != null) {
                final PreparedStatementSetter pss = (PreparedStatementSetter)new ArgumentPreparedStatementSetter(args);
                pss.setValues(ps);
            }
            return ps.executeUpdate();
        }
        catch (SQLException e) {
            DbUtil.log.error("executeUpdate Exception:", (Throwable)e);
            throw new ServiceException((IExceptionCode)ExceptionCode.DB_EXECUTE_EXCEPTION, (Throwable)e);
        }
        finally {
            if (isCloseConn) {
                close(conn, ps, null);
            }
            else if (ps != null) {
                try {
                    ps.close();
                }
                catch (SQLException e2) {
                    DbUtil.log.error("ps close Exception:", (Throwable)e2);
                }
            }
        }
    }
    
    public static void close(final Connection conn, final PreparedStatement ps, final ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
            if (ps != null) {
                ps.close();
            }
            if (conn != null) {
                conn.close();
            }
        }
        catch (Exception e) {
            DbUtil.log.error("close Exception:", (Throwable)e);
        }
    }
    
    public static void close(final Connection conn, final Statement st, final ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
            if (st != null) {
                st.close();
            }
            if (conn != null) {
                conn.close();
            }
        }
        catch (Exception e) {
            DbUtil.log.error("close Exception:", (Throwable)e);
        }
    }
    
    private static void println(final String sql, final Object[] args) {
        DbUtil.log.info("sql:{}", (Object)sql);
        final StringBuffer sb = new StringBuffer();
        if (args != null && args.length > 0) {
            for (final Object o : args) {
                if (sb.length() > 0) {
                    sb.append(",");
                }
                sb.append(String.valueOf(o));
            }
        }
        DbUtil.log.info("args:{}", (Object)sb.toString());
    }
    
    public static boolean executeUpdate2(final DataSource dataSource, final String sql, final Object[] args) {
        return execute(dataSource, (JdbcCallback<Boolean>)new JdbcCallback<Boolean>() {
            @Override
            public Boolean doInConnection(final Connection c) {
                PreparedStatement ps = null;
                try {
                    ps = c.prepareStatement(sql);
                    if (args != null) {
                        for (int i = 0; i < args.length; ++i) {
                            ps.setObject(i + 1, args[i]);
                        }
                    }
                    return ps.execute();
                }
                catch (SQLException e) {
                    DbUtil.log.error("SQLException81", (Throwable)e);
                    return false;
                }
                finally {
                    try {
                        if (ps != null) {
                            ps.close();
                        }
                    }
                    catch (SQLException e2) {
                        DbUtil.log.error("SQLException189", (Throwable)e2);
                    }
                }
            }
        });
    }
    
    private static <T> T execute(final DataSource dataSource, final JdbcCallback<T> callback) {
        Connection c = null;
        try {
            c = dataSource.getConnection();
            return callback.doInConnection(c);
        }
        catch (SQLException e2) {
            DbUtil.log.error("\u6267\u884c\u5f02\u5e38");
            return null;
        }
        finally {
            if (c != null) {
                try {
                    c.close();
                }
                catch (SQLException e) {
                    DbUtil.log.error("execute--SQLException", (Throwable)e);
                }
            }
        }
    }
    
    static {
        log = LoggerFactory.getLogger((Class)DbUtil.class);
    }
    
    private interface JdbcCallback<T>
    {
        T doInConnection(final Connection p0);
    }
}
